﻿using System;
using System.Linq;
using System.Collections.Generic;

namespace Sinacor.Infra.Tools.ServiceRegistration.Web
{
    public class ServiceController
    {
        #region Attributes

        #region Select Attributes

        private List<Entity.Module> _treeviewList;
        private List<Entity.Module> _moduleList;
        private List<Entity.SubModule> _submoduleList;
        private List<Entity.Service> _serviceList;
        private List<Entity.Method> _methodList;
        private List<Entity.Parameter> _parameterList;
        private List<Entity.Type> _typeList;
        private List<Entity.Attribute> _attributeList;
        private List<Entity.Type> _typeListStatic;        
        private List<Entity.Attribute> _attributeListStatic;        
        private List<Entity.Module> _module;
        private List<Entity.SubModule> _submodule;
        private List<Entity.Protocol> _protocol;
        
        #endregion

        #region Search Attributes

        private Entity.Module _moduleSearch;
        private Entity.SubModule _submoduleSearch;
        private Entity.Service _serviceSearch;
        private Entity.Method _methodSearch;
        private Entity.Parameter _parameterSearch;
        private Entity.Type _typeSearch;
        private Entity.Attribute _attributeSearch;

        #endregion

        #region Edit Attributes

        private Entity.Module _moduleEdit;
        private Entity.SubModule _submoduleEdit;
        private Entity.Service _serviceEdit;
        private Entity.Method _methodEdit;
        private Entity.Parameter _parameterEdit;
        private Entity.Type _typeEdit;
        private Entity.Attribute _attributeEdit;

        #endregion

        #region Business Attributes

        private Business.Module _bizModule;
        private Business.SubModule _bizSubModule;
        private Business.Service _bizService;
        private Business.Protocol _bizProtocol; 
        private Business.Method _bizMethod;
        private Business.Parameter _bizParameter;
        private Business.Type _bizType;
        private Business.Attribute _bizAttribute;

        #endregion

        #region Get Attributes

        private int _subModulePort;
        private bool _IsAttributePopupVisible;
        private int? _attributeParentTypeId;        

        #endregion

        #region View Attributes

        private IServiceController _view;

        #endregion

        #endregion

        #region Properties

        #region Select Properties

        public List<Entity.Module> TreeViewList
        {
            get { return _treeviewList; }
            set { _treeviewList = value; }
        }

        public List<Entity.Module> ModuleList
        {
            get { return _moduleList; }
            set { _moduleList = value; }
        }

        public List<Entity.SubModule> SubModuleList
        {
            get { return _submoduleList; }
            set { _submoduleList = value; }
        }

        public List<Entity.Service> ServiceList
        {
            get { return _serviceList; }
            set { _serviceList = value; }
        }

        public List<Entity.Method> MethodList
        {
            get { return _methodList; }
            set { _methodList = value; }
        }

        public List<Entity.Parameter> ParameterList
        {
            get { return _parameterList; }
            set { _parameterList = value; }
        }

        public List<Entity.Type> TypeList
        {
            get { return _typeList; }
            set { _typeList = value; }
        }

        public List<Entity.Attribute> AttributeList
        {
            get { return _attributeList; }
            set { _attributeList = value; }
        }

        public List<Entity.Type> TypeListStatic
        {
            get { return _typeListStatic; }
            set { _typeListStatic = value; }
        }

        public List<Entity.Attribute> AttributeListStatic
        {
            get { return _attributeListStatic; }
            set { _attributeListStatic = value; }
        }

        public List<Entity.Module> Module
        {
            get { return _module; }
            set { _module = value; }
        }

        public List<Entity.SubModule> SubModule
        {
            get { return _submodule; }
            set { _submodule = value; }
        }

        public List<Entity.Protocol> Protocol // inc - esertorio - 200810311921
        {
            get { return _protocol; }
            set { _protocol = value; }
        }

        #endregion

        #region Search Properties
        
        public Entity.Module ModuleSearch
        {
            get { return _moduleSearch; }
            set { _moduleSearch = value; }
        }

        public Entity.SubModule SubModuleSearch
        {
            get { return _submoduleSearch; }
            set { _submoduleSearch = value; }
        }

        public Entity.Service ServiceSearch
        {
            get { return _serviceSearch; }
            set { _serviceSearch = value; }
        }

        public Entity.Method MethodSearch
        {
            get { return _methodSearch; }
            set { _methodSearch = value; }
        }

        public Entity.Parameter ParameterSearch
        {
            get { return _parameterSearch; }
            set { _parameterSearch = value; }
        }

        public Entity.Type TypeSearch
        {
            get { return _typeSearch; }
            set { _typeSearch = value; }
        }

        public Entity.Attribute AttributeSearch
        {
            get { return _attributeSearch; }
            set { _attributeSearch = value; }
        }

        #endregion

        #region Edit Attributes

        public Entity.Module ModuleEdit
        {
            get { return _moduleEdit; }
            set { _moduleEdit = value; }
        }

        public Entity.SubModule SubModuleEdit
        {
            get { return _submoduleEdit; }
            set { _submoduleEdit = value; }
        }

        public Entity.Service ServiceEdit
        {
            get { return _serviceEdit; }
            set { _serviceEdit = value; }
        }

        public Entity.Method MethodEdit
        {
            get { return _methodEdit; }
            set { _methodEdit = value; }
        }

        public Entity.Parameter ParameterEdit
        {
            get { return _parameterEdit; }
            set { _parameterEdit = value; }
        }

        public Entity.Type TypeEdit
        {
            get { return _typeEdit; }
            set { _typeEdit = value; }
        }

        public Entity.Attribute AttributeEdit
        {
            get { return _attributeEdit; }
            set { _attributeEdit = value; }
        }

        #endregion

        #region Get Properties

        public int SubModulePort
        {
            get { return _subModulePort; }
            set { _subModulePort = value; }
        }

        public bool IsAttributePopupVisible
        {
            get { return _IsAttributePopupVisible; }
            set { _IsAttributePopupVisible = value; }
        }

        public int? AttributeParentTypeId
        {
            get { return _attributeParentTypeId; }
            set { _attributeParentTypeId = value; }
        }

        #endregion

        #region View Properties

        public IServiceController View
        {
            get { return _view; }
            set { _view = value; }
        }

        #endregion

        #endregion

        #region Constructor

        public ServiceController(IServiceController view)
        {
            this._view = view;
            this._bizModule = new Business.Module();
            this._bizSubModule = new Business.SubModule();
            this._bizService = new Business.Service();
            this._bizProtocol = new Business.Protocol(); //inc - esertorio - 200810311838
            this._bizMethod = new Business.Method();
            this._bizParameter = new Business.Parameter();
            this._bizType = new Business.Type();
            this._bizAttribute = new Business.Attribute();
        }

        #endregion

        #region Methods

        #region Select Methods

        public void SelectAll()
        {
            _treeviewList = _bizModule.SelectAll(_moduleSearch);

            _view.ShowTreeView();
        }

        public void SelectModule()
        {
            _module = _bizModule.SelectModule(new Entity.Module());

            _view.ShowModule();
        }

        public void SelectProtocol()
        {
            _protocol = _bizProtocol.SelectProtocol(new Entity.Protocol());

            _view.ShowProtocol();
        }

        public void SelectSubModule(int module_id)
        {
            _submodule = _bizSubModule.SelectSubModule(new Entity.SubModule() { Module = new Entity.Module() { ModuleId = module_id } });

            _view.ShowSubModule();
        }
    
        public void SelectModuleList()
        {
            if (_moduleSearch == null) _moduleSearch = new Entity.Module();

            _moduleList = _bizModule.SelectModule(_moduleSearch);

            _view.ShowModuleList();
        }

        public void SelectSubModuleList(int module_id)
        {
            if (_submoduleSearch == null)
            {
                _submoduleSearch = new Entity.SubModule();
                _submoduleSearch.Module = new Entity.Module();
            }

            _submoduleSearch.Module.ModuleId = module_id;

            _submoduleList = _bizSubModule.SelectSubModule(_submoduleSearch);

            _view.ShowSubModuleList();
        }

        public void SelectServiceList(int sub_module_id)
        {
            if (_serviceSearch == null)
            {
                _serviceSearch = new Entity.Service();
                _serviceSearch.SubModule = new Entity.SubModule();
            }

            _serviceSearch.SubModule.SubModuleId = sub_module_id;

            _serviceList = _bizService.SelectService(_serviceSearch);

            _view.ShowServiceList();
        }

        public void SelectMethodList(int service_id)
        {
            if (_methodSearch == null)
            {
                _methodSearch = new Entity.Method();
                _methodSearch.Service = new Entity.Service();
            }

            _methodSearch.Service.ServiceId = service_id;

            _methodList = _bizMethod.SelectMethod(_methodSearch);

            _view.ShowMethodList();
        }

        public void SelectParameterList(int method_id)
        {
            if (_parameterSearch == null)
            {
                _parameterSearch = new Entity.Parameter();
                _parameterSearch.Method = new Entity.Method();
            }

            _parameterSearch.Method.MethodId = method_id;

            _parameterList = _bizParameter.SelectParameter(_parameterSearch);

            _view.ShowParameterList();
        }

        public void SelectTypeListStatic()
        {
            if (_typeSearch == null)
                _typeSearch = new Entity.Type();

            _typeListStatic = _bizType.SelectType(_typeSearch);

            System.Web.HttpContext.Current.Application["TypeList"] = _typeListStatic;
        }

        public void SelectTypeList()
        {
            if (_typeSearch == null)
                _typeSearch = new Entity.Type();

            _typeList = _bizType.SelectType(_typeSearch);

            _view.ShowTypeList();
        }

        public void SelectAttributeListStatic()
        {
            if (_attributeSearch == null)
            {
                _attributeSearch = new Entity.Attribute();
                _attributeSearch.Type = new Entity.Type();
            }

            _attributeListStatic = _bizAttribute.SelectAttribute(_attributeSearch);
        }

        public void SelectAttributeList(int type_id)
        {
            if (_attributeSearch == null)
            {
                _attributeSearch = new Entity.Attribute();
                _attributeSearch.Type = new Entity.Type();
            }

            _attributeSearch.ParentTypeId = type_id;

            _attributeList = _bizAttribute.SelectAttribute(_attributeSearch);

            _view.ShowAttributeList();
        }
        
        #endregion

        #region Insert Methods

        public bool InsetModule()
        {
            bool isInserted = false;

            _moduleEdit = _bizModule.InsertModule(_moduleEdit);

            var p = from n in _moduleList
                    where n.ModuleId.Equals(_moduleEdit.ModuleId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _moduleList.Add(_moduleEdit);
                InsertTreeviewList(KindVision.Module);
                _view.ShowModuleList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
            
        }

        public bool InsetSubModule()
        {
            bool isInserted = false;

            _submoduleEdit = _bizSubModule.InsertSubModule(_submoduleEdit);

            var p = from n in _submoduleList
                    where n.SubModuleId.Equals(_submoduleEdit.SubModuleId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _submoduleList.Add(_submoduleEdit);
                InsertTreeviewList(KindVision.SubModule);
                _view.ShowSubModuleList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        public bool InsetService()
        {
            bool isInserted = false;

            _serviceEdit = _bizService.InsertService(_serviceEdit);

            var p = from n in _serviceList
                    where n.ServiceId.Equals(_serviceEdit.ServiceId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _serviceList.Add(_serviceEdit);
                InsertTreeviewList(KindVision.Service);
                _view.ShowServiceList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        public bool InsetMethod()
        {
            bool isInserted = false;

            _methodEdit = _bizMethod.InsertMethod(_methodEdit);

            var p = from n in _methodList
                    where n.MethodId.Equals(_methodEdit.MethodId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _methodList.Add(_methodEdit);
                InsertTreeviewList(KindVision.Method);
                _view.ShowMethodList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        public bool InsetParameter()
        {
            bool isInserted = false;

            _parameterEdit = _bizParameter.InsertParameter(_parameterEdit);

            var p = from n in _parameterList
                    where n.ParameterId.Equals(_parameterEdit.ParameterId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _parameterList.Add(_parameterEdit);
                InsertTreeviewList(KindVision.Parameter);
                _view.ShowParameterList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        public bool InsetType()
        {
            bool isInserted = false;

            _typeEdit = _bizType.InsertType(_typeEdit);

            var p = from n in _typeList
                    where n.TypeId.Equals(_typeEdit.TypeId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _typeList.Add(_typeEdit);
                _typeListStatic.Add(_typeEdit);
                _view.ShowTypeList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        public bool InsetAttribute()
        {
            bool isInserted = false;

            _attributeEdit = _bizAttribute.InsertAttribute(_attributeEdit);

            var p = from n in _attributeList
                    where n.AttributeId.Equals(_attributeEdit.AttributeId)
                    select n;

            isInserted = p.ToArray().Length == 0;

            if (isInserted)
            {
                _attributeList.Add(_attributeEdit);
                _attributeListStatic.Add(_attributeEdit);
                _view.ShowAttributeList();
            }
            else
                _view.ShowMessageError();

            return isInserted;
        }

        private void InsertTreeviewList(KindVision kindVision)
        {
            switch (kindVision)
            {
                case KindVision.Module:
                    _treeviewList.Add(_moduleEdit);
                    break;
                case KindVision.SubModule:
                    _treeviewList.Find(m => m.ModuleId == _submoduleEdit.Module.ModuleId).
                        SubModules.Add(_submoduleEdit);
                    break;
                case KindVision.Service:
                    _treeviewList.Find(m => m.ModuleId == _serviceEdit.SubModule.Module.ModuleId).
                        SubModules.Find(s => s.SubModuleId == _serviceEdit.SubModule.SubModuleId).
                            Services.Add(_serviceEdit);
                    break;
                case KindVision.Method:
                    _treeviewList.Find(m => m.ModuleId == _methodEdit.Service.SubModule.Module.ModuleId).
                        SubModules.Find(s => s.SubModuleId == _methodEdit.Service.SubModule.SubModuleId).
                            Services.Find(s => s.ServiceId == _methodEdit.Service.ServiceId).
                                Methods.Add(_methodEdit);
                    break;
                case KindVision.Parameter:
                    _treeviewList.Find(m => m.ModuleId == _parameterEdit.Method.Service.SubModule.Module.ModuleId).
                        SubModules.Find(s => s.SubModuleId == _parameterEdit.Method.Service.SubModule.SubModuleId).
                            Services.Find(s => s.ServiceId == _parameterEdit.Method.Service.ServiceId).
                                Methods.Find(m => m.MethodId == _parameterEdit.Method.MethodId).
                                    Parameters.Add(_parameterEdit);
                    break;
            };
        }

        #endregion

        #region Update Methods

        public void UpdateModule()
        {
            _bizModule.UpdateModule(_moduleEdit);

            Entity.Module module = _moduleList.Find(match => match.ModuleId == _moduleEdit.ModuleId);

            if (module != null)
            {
                module.ModuleName = _moduleEdit.ModuleName;
                module.ModuleInitials = _moduleEdit.ModuleInitials;
            }
            
            _view.ShowModuleList();
        }

        public void UpdateSubModule()
        {
            _bizSubModule.UpdateSubModule(_submoduleEdit);

            Entity.SubModule subModule = _submoduleList.Find(match => match.SubModuleId == _submoduleEdit.SubModuleId);

            if (subModule != null)
            {
                subModule.SubModuleName = _submoduleEdit.SubModuleName;
                subModule.Port = _submoduleEdit.Port;
            }

            _view.ShowSubModuleList();
        }

        public void UpdateService()
        {
            _bizService.UpdateService(_serviceEdit);

            Entity.Service service = _serviceList.Find(match => match.ServiceId == _serviceEdit.ServiceId);

            if (service != null)
            {
                service.ServiceName = _serviceEdit.ServiceName;
                service.Description = _serviceEdit.Description;
                service.EndPoints = _serviceEdit.EndPoints;
                service.StatusApproval = _serviceEdit.StatusApproval;
            }

            _view.ShowServiceList();
        }

        public void UpdateMethod()
        {
            _bizMethod.UpdateMethod(_methodEdit);

            Entity.Method method = _methodList.Find(match => match.MethodId == _methodEdit.MethodId);

            if (method != null)
            {
                method.MethodName = _methodEdit.MethodName;
                method.Description = _methodEdit.Description;
                method.RelatedTables = _methodEdit.RelatedTables;
                method.IsReturnCollection = _methodEdit.IsReturnCollection;
                method.ReturnType = _methodEdit.ReturnType;
                method.StatusApproval = _methodEdit.StatusApproval;
            }

            _view.ShowMethodList();
        }

        public void UpdateParameter()
        {
            _bizParameter.UpdateParameter(_parameterEdit);

            Entity.Parameter parameter = _parameterList.Find(match => match.ParameterId == _parameterEdit.ParameterId);

            if (parameter != null)
            {
                parameter.ParameterName = _parameterEdit.ParameterName;
                parameter.Description = _parameterEdit.Description;
                parameter.IsCollection = _parameterEdit.IsCollection;
                parameter.Type = _parameterEdit.Type;
            }

            _view.ShowParameterList();
        }

        public void UpdateType()
        {
            _bizType.UpdateType(_typeEdit);

            Entity.Type type = _typeList.Find(match => match.TypeId == _typeEdit.TypeId);

            if (type != null)
            {
                type.FullTypeName = _typeEdit.FullTypeName;
                type.Description = _typeEdit.Description;
            }

            type = _typeListStatic.Find(match => match.TypeId == _typeEdit.TypeId);

            if (type != null)
            {
                type.FullTypeName = _typeEdit.FullTypeName;
                type.Description = _typeEdit.Description;
            }

            _view.ShowTypeList();
        }

        public void UpdateAttribute()
        {
            _bizAttribute.UpdateAttribute(_attributeEdit);

            Entity.Attribute attribute = _attributeList.Find(match => match.AttributeId == _attributeEdit.AttributeId);

            if (attribute != null)
            {
                attribute.AttributeName = _attributeEdit.AttributeName;
                attribute.Description = _attributeEdit.Description;
                attribute.Type = _attributeEdit.Type;
            }

            attribute = _attributeListStatic.Find(match => match.AttributeId == _attributeEdit.AttributeId);

            if (attribute != null)
            {
                attribute.AttributeName = _attributeEdit.AttributeName;
                attribute.Description = _attributeEdit.Description;
                attribute.Type = _attributeEdit.Type;
            }

            _view.ShowAttributeList();
        }

        #endregion

        #region Delete Methods

        public void DeleteModule()
        {
            _bizModule.DeleteModule(_moduleEdit);

            Entity.Module module = _moduleList.Find(match => match.ModuleId == _moduleEdit.ModuleId);

            if (module != null)
                _moduleList.Remove(module);

            _view.ShowModuleList();
        }

        public void DeleteSubModule()
        {
            _bizSubModule.DeleteSubModule(_submoduleEdit);

            Entity.SubModule subModule = _submoduleList.Find(match => match.SubModuleId == _submoduleEdit.SubModuleId);

            if (subModule != null)
                _submoduleList.Remove(subModule);

            _view.ShowSubModuleList();
        }

        public void DeleteService()
        {
            _bizService.DeleteService(_serviceEdit);

            Entity.Service service = _serviceList.Find(match => match.ServiceId == _serviceEdit.ServiceId);

            if (service != null)
                _serviceList.Remove(service);

            _view.ShowServiceList();
        }

        public void DeleteMethod()
        {
            _bizMethod.DeleteMethod(_methodEdit);

            Entity.Method method = _methodList.Find(match => match.MethodId == _methodEdit.MethodId);

            if (method != null)
                _methodList.Remove(method);

            _view.ShowMethodList();
        }

        public void DeleteParameter()
        {
            _bizParameter.DeleteParameter(_parameterEdit);

            Entity.Parameter parameter = _parameterList.Find(match => match.ParameterId == _parameterEdit.ParameterId);

            if (parameter != null)
                _parameterList.Remove(parameter);

            _view.ShowParameterList();
        }

        public void DeleteType()
        {
            _bizType.DeleteType(_typeEdit);

            Entity.Type type = _typeList.Find(match => match.TypeId == _typeEdit.TypeId);

            if (type != null)
                _typeList.Remove(type);

            type = _typeListStatic.Find(match => match.TypeId == _typeEdit.TypeId);

            if (type != null)
                _typeListStatic.Remove(type);

            _view.ShowTypeList();
        }

        public void DeleteAttribute()
        {
            _bizAttribute.DeleteAttribute(_attributeEdit);

            Entity.Attribute attribute = _attributeList.Find(match => match.AttributeId == _attributeEdit.AttributeId);

            if (attribute != null)
                _attributeList.Remove(attribute);

            attribute = _attributeListStatic.Find(match => match.AttributeId == _attributeEdit.AttributeId);

            if (attribute != null)
                _attributeListStatic.Remove(attribute);

            _view.ShowAttributeList();
        }

        #endregion

        #region Get

        public void GetNextSubModulePort()
        {
            _subModulePort = _bizSubModule.GetNextSubModulePort();

            View.ShowSubModulePort();
        }

        #endregion

        #endregion
    }
}